/*
leetcode 121: https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/description/?envType=study-plan-v2&envId=top-interview-150

题目描述：
给定一个数组 prices ，它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票，并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润，返回 0 。

示例 1：
输入：[7,1,5,3,6,4]
输出：5
解释：在第 2 天（股票价格 = 1）的时候买入，在第 5 天（股票价格 = 6）的时候卖出，最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格；同时，你不能在买入前卖出股票。

示例 2：
输入：prices = [7,6,4,3,1]
输出：0
解释：在这种情况下, 没有交易完成, 所以最大利润为 0。
 

提示：
1 <= prices.length <= 10^5
0 <= prices[i] <= 10^4

解题思路：
1. 暴力解法：双for循环遍历，时间复杂度O(n^2)
2. 一次遍历：找到最低点，时间复杂度O(n)

*/
//==================================222==============================//
/*
leetcode 122 : https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/description/?envType=study-plan-v2&envId=top-interview-150
题目描述：
给你一个整数数组 prices ，其中 prices[i] 表示某支股票第 i 天的价格。

在每一天，你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买，然后在 同一天 出售。

返回 你能获得的 最大 利润 。

示例 1：
输入：prices = [7,1,5,3,6,4]
输出：7
解释：在第 2 天（股票价格 = 1）的时候买入，在第 3 天（股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
随后，在第 4 天（股票价格 = 3）的时候买入，在第 5 天（股票价格 = 6）的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。
最大总利润为 4 + 3 = 7 。

示例 2：
输入：prices = [1,2,3,4,5]
输出：4
解释：在第 1 天（股票价格 = 1）的时候买入，在第 5 天 （股票价格 = 5）的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。
最大总利润为 4 。

示例 3：
输入：prices = [7,6,4,3,1]
输出：0
解释：在这种情况下, 交易无法获得正利润，所以不参与交易可以获得最大利润，最大利润为 0。
 

提示：

1 <= prices.length <= 3 * 10^4
0 <= prices[i] <= 10^4

解题思路：
1. 动态规划DP：
2. 贪心算法：由于股票的购买没有限制，因此整个问题等价于寻找 x 个不相交的区间(l, r]的差值累加最大化，
            可以简化成x-（x-1）长度为1的累加最大值
3. 股票模拟法：模拟股票收益，计算折线上升区间，累加即可
            
*/
#include <iostream>
#include <vector>

using namespace std;

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        int max = 0;

        for(int i = 0; i < n; i++) {
            for(int j = i+1; j < n; j++) {
                int profit = prices[j] - prices[i];
                if(profit > max) {
                    max = profit;
                }
            }
        }
         return max;
    }
};

class Solution2 {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        int max_profit = 0;
        int min_price = 10000; //记录历史最小值

        for(int i = 0; i < n; i++) {
            max_profit = max(max_profit, prices[i] - min_price); //计算最大收益
            min_price = min(prices[i], min_price);//计算最小值
        }

        return max_profit;
    }
};

//====题型2
//动态规划
class Solution_1 {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        int dp0 = 0, dp1 = -prices[0];
        for (int i = 1; i < n; ++i) {
            int newDp0 = max(dp0, dp1 + prices[i]);
            int newDp1 = max(dp1, dp0 - prices[i]);
            dp0 = newDp0;
            dp1 = newDp1;
        }
        return dp0;
    }
};
//贪心算法
class Solution_2 {
public:
    int maxProfit(vector<int>& prices) {   
        int ans = 0;
        int n = prices.size();
        for (int i = 1; i < n; ++i) {
            ans += max(0, prices[i] - prices[i - 1]);
        }
        return ans;
    }
};
//股票模拟法
class Solution_3 {
public:
     int maxProfit(vector<int>& prices) {
        int sum = 0;
        for (int i = 1; i < prices.size(); i++) {
            if (prices[i] > prices[i - 1]) {
                int temp = prices[i] - prices[i - 1];
                sum += temp;
            }
        }
        return sum;
    }
};





int main() {
    vector <int> prices = {7, 1, 5, 3, 6, 4};

    Solution_3 solution;
    int max_profit = solution.maxProfit(prices);

    cout << "max profit: " << max_profit << endl;


    return 0;
}